﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Linq.Expressions;
using System.Web;
using Aspose.Cells;
using System.IO;
using Small.Express;
using System.Reflection;
using System.Data;

namespace Small.Excel
{
    public class SmartExcel : IExcelHelper
    {

        private Workbook workbook;

        public Workbook Workbook
        {
            get { return workbook; }

        }

        public SmartExcel(string path)
        {
            workbook = new Workbook(path);
        }

        public SmartExcel(Stream stream)
        {

            workbook = new Workbook(stream);
        }

        public void Write<T>(IQueryable<T> source, ExcelSheetOptions options, Expression<Func<T, object>>[] fields = null)
        {

            IList<string> fieldList = null;
            Worksheet sheet = workbook.Worksheets[options.SheetIndex];

            if (fieldList == null)
            {
                fieldList = new List<String>();
                PropertyInfo[] Properties = typeof(T).GetProperties();
                foreach (var item in Properties)
                {
                    fieldList.Add(item.Name);

                }
            }
            else
            {
                fieldList = (IList<String>)BaseExpress.ExpressItems<T>(fields).Select(p => p.Text);
            }
            int sourceIndex = 0;
            foreach (T item in source)
            {
               
                int columnStartIndex = options.StartColumn;
                

                foreach (var field in fieldList)
                {
                    sheet.Cells[options.StartRowIndex + sourceIndex, columnStartIndex++].Value =
                        item.GetType().GetProperty(field).GetValue(item);
                }
                sourceIndex++;
            }
        }

        public void Export(HttpContext context, string fileName, SaveFormat format = SaveFormat.Xlsx)
        {
            

            //下载模板到客户端

            string tempFileName = string.Format("{0}", fileName);
            workbook.Save(context.Response, context.Server.UrlEncode(fileName)+"."+format.ToString().ToLower(), ContentDisposition.Attachment, new OoxmlSaveOptions(format));
            //HttpContext.Current.Response.End();
            context.Response.End();

            
        }

        public void Export(string fileName, SaveFormat format=SaveFormat.Xlsx)
        {
            workbook.Save(String.Format("{0}.{1}",fileName, format.ToString().ToLower()),format);

        }

        public void Export(Stream stream, SaveFormat format = SaveFormat.Xlsx)
        {
            workbook.Save(stream, format);

        }

        /// <summary>
        /// 导入Excel
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="options"></param>
        /// <param name="fields"></param>
        /// <returns></returns>
        public IQueryable<T> Import<T>(ExcelSheetOptions options, Expression<Func<T, object>>[] fields=null) where T : new()
        {

            List<T> list = new List<T>();
             List<String> fieldList=null;
            if (fieldList == null)
            {
                fieldList = new List<String>();
                PropertyInfo[] Properties = typeof(T).GetProperties();
                foreach (var item in Properties)
                {
                    fieldList.Add(item.Name);

                }
            }
            else{
                fieldList = (List<String>)BaseExpress.ExpressItems<T>(fields).Select(p => p.Text);
            }
            DataTable table = GetDataTable(options);

            for (int i = 0; i < table.Rows.Count; i++)
            {


                T t = new T();

                for (int j = 0; j < fieldList.Count; j++)
                {

                    PropertyInfo propertyInfo = t.GetType().GetProperty(fieldList[j]);
                    ConvertProperty.SetThisValue<T>(t, fieldList[j], table.Rows[i][j]);

                    

                }

                list.Add(t); 
            }


            return list.AsQueryable<T>();
        }
        /// <summary>
        /// 导入Excel
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public DataTable Import(ExcelSheetOptions options)
        {
            return GetDataTable(options);
        }

        private DataTable GetDataTable(ExcelSheetOptions options)
        {
            Worksheet sheet = workbook.Worksheets[options.SheetIndex];
            Cells cells = sheet.Cells;
            DataTable table = cells.ExportDataTable(options.StartRowIndex, options.StartColumn,
                                                        cells.MaxDataRow + 1, cells.MaxDataColumn + 1,true);
            return table;

        }




       

       
    }
}
